<template>
  <div class="page-container">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="page-title">
        <div class="title-with-back">
          <el-button 
            type="primary" 
            :icon="ArrowLeft" 
            @click="$router.push('/tools')"
            class="blue-return-button"
            circle
          />
          <div class="title-content">
            <div class="title-main">
              <el-icon class="title-icon"><Monitor /></el-icon>
              <h2>Kafka数据监听</h2>
            </div>
            <p class="page-description">
              <el-icon><Document /></el-icon>
              <span>实时监听Kafka数据流，支持智能匹配和过滤</span>
            </p>
          </div>
        </div>
      </div>
      <div class="page-actions">
        <el-tag v-if="monitoring" type="success" :icon="VideoPlay">监听中</el-tag>
        <el-tag v-else type="info" :icon="VideoPause">已停止</el-tag>
      </div>
    </div>

    <!-- 配置面板 -->
    <el-card class="config-panel">
      <template #header>
        <div class="card-header">
          <div class="card-header-title">
            <el-icon class="card-icon"><Setting /></el-icon>
            <span>监听配置</span>
          </div>
          <el-button @click="loadEnvironments" :icon="Refresh" size="small">刷新</el-button>
        </div>
      </template>
      
      <el-form :model="config" label-width="100px" :inline="true">
        <!-- 基础配置 -->
        <el-form-item label="Kafka环境" required>
          <el-select 
            v-model="config.kafka_config_id" 
            @change="loadTopics" 
            @focus="onEnvironmentSelectFocus"
            style="width: 200px"
            :loading="environmentsLoading"
            placeholder="选择环境"
          >
            <el-option 
              v-for="env in kafkaEnvironments" 
              :key="env.id" 
              :label="env.config_name" 
              :value="env.id"
            >
              <div style="display: flex; justify-content: space-between;">
                <span>{{ env.config_name }}</span>
                <span style="color: #8492a6; font-size: 12px">{{ env.host }}:{{ env.port }}</span>
              </div>
            </el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="Topic" required>
          <div style="display: flex; gap: 8px; align-items: center;">
            <el-autocomplete
              v-model="config.topic"
              :fetch-suggestions="queryTopicSuggestions"
              placeholder="输入或选择topic"
              style="width: 250px"
              clearable
              :trigger-on-focus="true"
              @select="handleTopicSelect"
              :debounce="300"
            >
              <template #default="{ item }">
                <div class="topic-suggestion-item">
                  <el-icon><Menu /></el-icon>
                  <span>{{ item.value }}</span>
                </div>
              </template>
            </el-autocomplete>
            <el-button @click="openTopicSelector" :icon="Menu" title="从列表选择" size="small"></el-button>
          </div>
        </el-form-item>

        <el-form-item label="消费策略">
          <el-select v-model="config.consume_strategy" style="width: 120px">
            <el-option label="最新" value="latest" />
            <el-option label="最早" value="earliest" />
            <el-option label="指定时间" value="timestamp" />
          </el-select>
        </el-form-item>

        <el-form-item v-if="config.consume_strategy === 'timestamp'" label="开始时间">
          <el-input 
            v-model="timestampDisplay"
            placeholder="选择开始时间"
            readonly
            style="width: 320px; cursor: pointer;"
            @click="openTimestampDialog"
          >
            <template #suffix>
              <el-icon style="cursor: pointer; color: #409EFF;" @click="openTimestampDialog">
                <Clock />
              </el-icon>
            </template>
          </el-input>
        </el-form-item>

        <el-form-item>
          <el-button 
            @click="startMonitoring" 
            type="primary" 
            :loading="monitoring"
            :disabled="!canStart"
            :icon="monitoring ? Loading : VideoPlay"
          >
            {{ monitoring ? '监听中...' : '开始监听' }}
          </el-button>
          <el-button 
            @click="stopMonitoring" 
            :disabled="!monitoring"
            :icon="VideoPause"
          >
            停止
          </el-button>
        </el-form-item>
      </el-form>

      <!-- 数据匹配配置 -->
      <el-divider content-position="left">
        <span>数据匹配配置</span>
        <el-tooltip content="设置多个匹配条件，支持AND/OR逻辑组合" placement="top">
          <el-icon style="margin-left: 5px;"><QuestionFilled /></el-icon>
        </el-tooltip>
      </el-divider>
      
      <div class="match-config-container">
        <!-- 全局开关 -->
        <div class="match-global-control">
          <el-radio-group v-model="config.enableMatching" class="match-enable-selector">
            <el-radio :value="false">显示所有消息</el-radio>
            <el-radio :value="true">启用条件匹配</el-radio>
          </el-radio-group>
        </div>

        <!-- 匹配条件配置 -->
        <div v-if="config.enableMatching" class="match-conditions">
          <!-- 逻辑关系选择 -->
          <div class="logic-selector">
            <label class="control-label">多条件逻辑关系：</label>
            <el-radio-group v-model="config.logicOperator" class="logic-operator">
              <el-radio value="AND">
                <el-tag type="success">AND (与)</el-tag>
                <span style="margin-left: 8px; color: #666;">所有条件都必须满足</span>
              </el-radio>
              <el-radio value="OR">
                <el-tag type="warning">OR (或)</el-tag>
                <span style="margin-left: 8px; color: #666;">任意条件满足即可</span>
              </el-radio>
            </el-radio-group>
          </div>

          <!-- 匹配条件列表 -->
          <div class="conditions-list">
            <div v-for="(condition, index) in config.matchConditions" :key="index" class="condition-item">
              <el-card shadow="never" class="condition-card">
                <div class="condition-header">
                  <span class="condition-number">条件 {{ index + 1 }}</span>
                  <el-button 
                    @click="removeCondition(index)" 
                    type="danger" 
                    size="small" 
                    :icon="Delete"
                    circle
                    :disabled="config.matchConditions.length === 1"
                  />
                </div>
                
                <div class="condition-content">
                  <!-- 匹配类型 -->
                  <div class="condition-row">
                    <label class="condition-label">匹配类型：</label>
                    <el-radio-group v-model="condition.type" class="condition-type">
                      <el-radio value="key_value">键值对匹配</el-radio>
                      <el-radio value="fuzzy">模糊匹配</el-radio>
                    </el-radio-group>
                  </div>

                  <!-- 键值对匹配输入 -->
                  <div v-if="condition.type === 'key_value'" class="condition-row">
                    <div class="input-group">
                      <label class="input-label">键名 (Key) - 完整路径</label>
                      <el-input
                        v-model="condition.key"
                        placeholder="例如: data.itemId"
                        style="width: 200px"
                      />
                    </div>
                    <div class="input-group">
                      <label class="input-label">键值 (Value)</label>
                      <el-input
                        v-model="condition.value"
                        placeholder="例如: 12345"
                        style="width: 200px"
                      />
                    </div>
                  </div>

                  <!-- 模糊匹配输入 -->
                  <div v-else-if="condition.type === 'fuzzy'" class="condition-row">
                    <div class="input-group">
                      <label class="input-label">匹配值</label>
                      <el-input
                        v-model="condition.value"
                        placeholder="输入要匹配的内容"
                        style="width: 300px"
                      />
                      <span v-if="condition.value" style="margin-left: 10px; color: #909399; font-size: 12px;">
                        长度: {{ condition.value.length }} 字符
                      </span>
                    </div>
                  </div>
                </div>
              </el-card>
            </div>

            <!-- 添加条件按钮 -->
            <div class="add-condition">
              <el-button @click="addCondition" type="primary" :icon="Plus" size="small">
                添加匹配条件
              </el-button>
            </div>
          </div>
        </div>
      </div>
    </el-card>

    <!-- 数据展示面板 -->
    <el-card class="data-panel">
      <template #header>
        <div class="data-header">
          <div class="card-header-title">
            <el-icon class="card-icon"><DataLine /></el-icon>
            <span>监听数据</span>
          </div>
          <div class="data-actions">
            <el-checkbox v-model="displayConfig.auto_scroll">自动滚动到底部</el-checkbox>
            <el-checkbox v-model="displayConfig.show_timestamp">显示时间戳</el-checkbox>
            <el-button @click="clearMessages" :icon="Delete" size="small">清空显示</el-button>
            <el-button @click="exportData" :icon="Download" size="small">导出JSON</el-button>
          </div>
        </div>
      </template>
      
      <!-- 监听状态信息 -->
      <div class="data-stats">
        <el-statistic 
          title="监听状态" 
          :value="monitoring ? '运行中' : '已停止'" 
          :value-style="{ color: monitoring ? '#67C23A' : '#909399' }" 
        />
        <el-statistic 
          title="监听时长" 
          :value="formatDurationFromSeconds(monitoringDuration)" 
          v-if="monitoring"
        />
        <el-statistic 
          title="消费消息数" 
          :value="messageStats.total_consumed" 
          :value-style="{ color: '#409EFF' }"
          suffix="条"
          v-if="monitoring"
        />
        <el-statistic 
          title="匹配消息数" 
          :value="messageStats.total_matched" 
          :value-style="{ color: messageStats.total_matched > 0 ? '#67C23A' : '#909399' }"
          suffix="条"
          v-if="monitoring && config.enableMatching"
        />
        <el-statistic 
          title="匹配条件" 
          :value="config.enableMatching ? config.matchConditions.length : 0" 
          suffix="个"
        />
      </div>

      <!-- 监听状态显示 -->
      <div class="message-list" ref="messageContainer">
        <!-- 监听状态信息 -->
        <div v-if="monitoring || messages.length > 0">
          <!-- 正在监听时的状态 -->
          <div v-if="monitoring" class="listening-status" style="margin-bottom: 16px;">
            <el-alert
              title="Kafka数据监听中"
              type="success"
              :closable="false"
              show-icon
            >
              <template #default>
                <div style="display: flex; align-items: center; gap: 20px;">
                  <span><strong>任务ID:</strong> {{ currentTaskId }}</span>
                  <span><strong>Topic:</strong> {{ config.topic }}</span>
                  <span><strong>时长:</strong> {{ formatDurationFromSeconds(monitoringDuration) }}</span>
                  <span><strong>消息数:</strong> {{ messages.length }}</span>
                  <el-button @click="stopMonitoring" type="danger" size="small">停止监听</el-button>
                </div>
              </template>
            </el-alert>
          </div>
          
          <!-- 已停止监听时的状态 -->
          <div v-else class="stopped-status" style="margin-bottom: 16px;">
            <el-alert
              title="监听已停止"
              type="info"
              :closable="false"
              show-icon
            >
              <template #default>
                <div style="display: flex; align-items: center; gap: 20px;">
                  <span><strong>消息数:</strong> {{ messages.length }}</span>
                  <span><strong>状态:</strong> 数据已保留供查看</span>
                  <div style="display: flex; gap: 8px;">
                    <el-button @click="startMonitoring" type="primary" size="small" :disabled="!canStart">重新开始监听</el-button>
                    <el-button @click="clearMessages" type="warning" size="small">清空消息</el-button>
                  </div>
                </div>
              </template>
            </el-alert>
          </div>

          <!-- Kafka配置信息 -->
          <div v-if="kafkaConfig && Object.keys(kafkaConfig).length > 0" class="kafka-config-panel" style="margin-bottom: 16px;">
            <el-card>
              <template #header>
                <div style="display: flex; align-items: center; gap: 10px;">
                  <el-icon><Setting /></el-icon>
                  <span>Kafka消费者配置</span>
                  <el-tag size="small" type="info">实际参数</el-tag>
                </div>
              </template>
              
              <div class="config-grid">
                <div class="config-item">
                  <label>Topic:</label>
                  <el-tooltip :content="kafkaConfig.topic" placement="top" :disabled="!kafkaConfig.topic || kafkaConfig.topic.length < 50">
                    <span class="topic-text">{{ kafkaConfig.topic }}</span>
                  </el-tooltip>
                </div>
                <div class="config-item">
                  <label>消费策略:</label>
                  <el-tag :type="getStrategyTagType(kafkaConfig.consume_strategy)" size="small">
                    {{ getStrategyText(kafkaConfig.consume_strategy) }}
                  </el-tag>
                </div>
                <div class="config-item">
                  <label>Group ID:</label>
                  <code>{{ kafkaConfig.group_id }}</code>
                </div>
                <div class="config-item" v-if="kafkaConfig.start_timestamp">
                  <label>开始时间戳:</label>
                  <span>{{ new Date(kafkaConfig.start_timestamp).toLocaleString() }}</span>
                </div>
                <div class="config-item">
                  <label>Bootstrap Servers:</label>
                  <span>{{ Array.isArray(kafkaConfig.bootstrap_servers) ? kafkaConfig.bootstrap_servers.join(', ') : kafkaConfig.bootstrap_servers }}</span>
                </div>
                <div class="config-item">
                  <label>Auto Offset Reset:</label>
                  <span>{{ kafkaConfig.auto_offset_reset }}</span>
                </div>
                <div class="config-item">
                  <label>Auto Commit:</label>
                  <el-tag :type="kafkaConfig.enable_auto_commit ? 'success' : 'warning'" size="small">
                    {{ kafkaConfig.enable_auto_commit ? '启用' : '禁用' }}
                  </el-tag>
                </div>
                <div class="config-item" v-if="kafkaConfig.enable_auto_commit">
                  <label>Commit间隔:</label>
                  <span>{{ kafkaConfig.auto_commit_interval_ms }}ms</span>
                </div>
                <div class="config-item">
                  <label>最大拉取记录:</label>
                  <span>{{ kafkaConfig.max_poll_records }}</span>
                </div>
                <!-- 认证信息已隐藏，不在页面显示 -->
              </div>
            </el-card>
          </div>

          <!-- 消息列表 -->
          <div v-if="messages.length > 0" class="messages-container">
            <div 
              v-for="(message, index) in messages" 
              :key="index"
              class="message-item"
              :class="{ 'matched': message.is_matched }"
            >
              <div class="message-header">
                <div class="header-left">
                  <span class="message-index">#{{ index + 1 }}</span>
                  <span class="message-time" v-if="displayConfig.show_timestamp">
                    {{ new Date(message.timestamp).toLocaleString() }}
                  </span>
                  <el-tag 
                    v-if="message.is_matched" 
                    type="success" 
                    size="small"
                  >
                    匹配
                  </el-tag>
                  <el-tag 
                    v-else 
                    type="info" 
                    size="small"
                  >
                    普通
                  </el-tag>
                  <el-tag 
                    v-if="!monitoring" 
                    type="warning" 
                    size="small"
                  >
                    已保存
                  </el-tag>
                </div>
                <div class="header-right">
                  <el-button 
                    @click="toggleMessageExpand(index)" 
                    :icon="message.expanded ? 'ArrowUp' : 'ArrowDown'"
                    size="small"
                    text
                    type="primary"
                  >
                    {{ message.expanded ? '折叠' : '展开' }}
                  </el-button>
                  <el-button 
                    @click="copyMessage(message)" 
                    icon="DocumentCopy"
                    size="small"
                    text
                    type="info"
                    title="复制JSON"
                  />
                </div>
              </div>
              <div class="message-content" v-show="message.expanded">
                <div class="json-viewer">
                  <pre class="json-content">{{ formatMessage(message) }}</pre>
                </div>
              </div>
              <div class="message-preview" v-show="!message.expanded" @click="toggleMessageExpand(index)">
                <span class="preview-text">{{ getMessagePreview(message) }}</span>
              </div>
            </div>
          </div>

          <!-- 无消息提示 -->
          <div v-else class="no-messages">
            <el-empty description="暂无消息" :image-size="100">
              <template #description>
                <p>正在监听 {{ config.topic }}，等待消息到达...</p>
              </template>
            </el-empty>
          </div>
        </div>

        <!-- 空状态 -->
        <el-empty 
          v-else 
          description="点击开始监听来启动Kafka数据监听"
        >
          <el-button @click="startMonitoring" type="primary" :disabled="!canStart">
            开始监听
          </el-button>
        </el-empty>
      </div>
    </el-card>

    <!-- 时间戳选择器弹窗 -->
    <el-dialog v-model="showTimestampDialog" title="选择时间戳" width="600px">
      <div class="timestamp-dialog">
        <div class="timestamp-info">
          <el-alert 
            title="时间戳说明" 
            type="info" 
            :closable="false"
            show-icon
          >
            <p>选择消费开始时间，系统将从指定时间点开始消费Kafka消息</p>
            <p>• 日期时间将自动转换为毫秒时间戳</p>
            <p>• 如果指定时间没有消息，将从下一条可用消息开始</p>
          </el-alert>
        </div>
        
        <div class="timestamp-selector">
          <div class="datetime-inputs">
            <div class="input-group">
              <label>选择日期:</label>
              <el-date-picker
                v-model="tempDate"
                type="date"
                placeholder="选择日期"
                format="YYYY-MM-DD"
                value-format="YYYY-MM-DD"
                style="width: 200px"
              />
            </div>
            
            <div class="input-group">
              <label>选择时间:</label>
              <el-time-picker
                v-model="tempTime"
                format="HH:mm:ss"
                value-format="HH:mm:ss"
                placeholder="选择时间"
                style="width: 200px"
              />
            </div>
          </div>
          
          <div class="timestamp-preview">
            <div class="preview-info">
              <label>时间戳预览:</label>
              <div class="preview-values">
                <div class="preview-item">
                  <span class="label">日期时间:</span>
                  <code>{{ tempDate && tempTime ? `${tempDate} ${tempTime}` : '请选择日期和时间' }}</code>
                </div>
                <div class="preview-item">
                  <span class="label">毫秒时间戳:</span>
                  <code>{{ tempDate && tempTime ? getTimestampPreview() : '0' }}</code>
                </div>
              </div>
            </div>
          </div>
          
          <div class="quick-select-section">
            <div class="quick-select-info">
              <label>快捷选择:</label>
              <p class="usage-tip">该时间戳将用作Kafka消费的起始位置，消费该时间点之后的消息</p>
            </div>
            <div class="quick-select-buttons">
              <el-button size="small" @click="setQuickTime('1h')">1小时前</el-button>
              <el-button size="small" @click="setQuickTime('6h')">6小时前</el-button>
              <el-button size="small" @click="setQuickTime('12h')">12小时前</el-button>
              <el-button size="small" @click="setQuickTime('today')">今天开始</el-button>
              <el-button size="small" @click="setQuickTime('yesterday')">昨天开始</el-button>
            </div>
          </div>
        </div>
      </div>
      
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="showTimestampDialog = false">取消</el-button>
          <el-button type="primary" @click="confirmTimestamp">插入时间戳</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- Topic选择器弹窗 -->
    <el-dialog 
      v-model="showTopicSelector" 
      width="700px"
      :close-on-click-modal="false"
      class="unified-dialog"
    >
      <template #header>
        <div class="dialog-header">
          <div class="header-icon header-icon-primary">
            <el-icon><List /></el-icon>
          </div>
          <div class="header-content">
            <h3>输入或选择topic</h3>
            <p>从可用的Topic列表中选择</p>
          </div>
        </div>
      </template>
      
      <div class="dialog-content">
      <div style="margin-bottom: 16px;">
        <div style="display: flex; gap: 12px; align-items: center;">
          <el-input
            v-model="topicSearchKeyword"
            placeholder="搜索Topic名称..."
            :prefix-icon="Search"
            clearable
            style="flex: 1;"
            @input="handleTopicSearch"
          />
          <el-button @click="loadTopics" :loading="topicsLoading" :icon="Refresh">刷新</el-button>
        </div>
        
        <!-- 搜索统计信息 -->
        <div v-if="topicSearchKeyword" style="margin-top: 8px; font-size: 12px; color: #909399;">
          找到 {{ filteredTopics.length }} 个匹配的Topic（共 {{ topics.length }} 个）
        </div>
      </div>
      
      <el-table 
        :data="filteredTopics" 
        height="350px"
        @row-click="selectTopic"
        style="cursor: pointer;"
        :empty-text="topicSearchKeyword ? '未找到匹配的Topic' : '暂无Topic数据'"
      >
        <el-table-column prop="name" label="Topic名称">
          <template #default="{ row }">
            <div v-if="topicSearchKeyword">
              <span v-html="highlightSearchKeyword(row.name)"></span>
            </div>
            <span v-else>{{ row.name }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="100">
          <template #default="{ row }">
            <el-button size="small" @click.stop="selectTopic(row)" type="primary">选择</el-button>
          </template>
        </el-table-column>
      </el-table>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, onUnmounted, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { 
  Delete, Plus, Download, VideoPlay, VideoPause, QuestionFilled, 
  Refresh, Loading, Search, Menu, ArrowLeft, Clock, ArrowUp, ArrowDown, DocumentCopy,
  Setting, Monitor, Document, DataLine
} from '@element-plus/icons-vue'
import { componentLogger } from '@/utils/logger'
import { copyToClipboard as copyText, copyJsonToClipboard } from '@/utils/clipboard'
import api from '@/utils/api'
import { formatDurationFromSeconds } from '@/utils/duration'

// 响应式数据
const config = reactive({
  kafka_config_id: null,
  topic: '',
  consume_strategy: 'latest',
  start_time: null,
  enableMatching: false,
  logicOperator: 'AND',
  matchConditions: [
    {
      type: 'key_value',
      key: '',
      value: ''
    }
  ]
})

const kafkaEnvironments = ref([])
const topics = ref([])
const monitoring = ref(false)

const messageStats = ref({
  total_consumed: 0,
  total_matched: 0
})

const displayConfig = reactive({
  auto_scroll: true,
  show_timestamp: true,
  max_messages: 1000
})

const environmentsLoading = ref(false)
const topicsLoading = ref(false)
const showTopicSelector = ref(false)
const showTimestampDialog = ref(false)
const currentTaskId = ref(null)
const monitoringStartTime = ref(null)
const monitoringDuration = ref(0)
const statusCheckTimer = ref(null)

// 时间戳选择器相关
const tempDate = ref('')
const tempTime = ref('')
const timestampDisplay = ref('')

// Topic搜索相关
const topicSearchKeyword = ref('')
const filteredTopics = ref([])

const canStart = computed(() => {
  return config.kafka_config_id && config.topic && !monitoring.value
})

// 消息容器引用
const messageContainer = ref(null)

// 消息数据
const messages = ref([])
const messagesLoading = ref(false)
const messageCheckTimer = ref(null)

// Kafka配置信息
const kafkaConfig = ref({})

// 定时器更新监听时长
const durationTimer = ref(null)

// 方法
// 环境选择器聚焦时加载环境列表（只加载一次）
const onEnvironmentSelectFocus = () => {
  if (kafkaEnvironments.value.length === 0 && !environmentsLoading.value) {
    loadEnvironments()
  }
}

const loadEnvironments = async () => {
  // 防止重复加载
  if (environmentsLoading.value) {
    componentLogger.warn('环境加载中,请稍候')
    return
  }
  
  environmentsLoading.value = true
  try {
    const response = await api.get('/kafka-listener/environments', {
      timeout: 10000 // 10秒超时
    })
    if (response.data.success) {
      kafkaEnvironments.value = response.data.data || []
      if (kafkaEnvironments.value.length === 0) {
        ElMessage.warning('未找到可用的Kafka环境配置')
      } else {
        componentLogger.info('Kafka环境加载成功', { count: kafkaEnvironments.value.length })
      }
    } else {
      throw new Error(response.data.message || '获取环境失败')
    }
  } catch (error) {
    componentLogger.error('加载Kafka环境失败', error)
    kafkaEnvironments.value = [] // 确保清空
    ElMessage.error({
      message: '加载Kafka环境失败: ' + (error.message || '网络错误'),
      duration: 5000
    })
  } finally {
    environmentsLoading.value = false
  }
}

const loadTopics = async () => {
  if (!config.kafka_config_id) return
  
  topicsLoading.value = true
  try {
    const response = await api.get('/kafka-listener/topics', {
      params: { kafka_config_id: config.kafka_config_id }
    })
    if (response.data.success) {
      // 将字符串数组转换为对象数组以支持表格显示
      topics.value = response.data.data.map(topicName => ({ name: topicName }))
      // 初始化过滤列表
      filteredTopics.value = [...topics.value]
      componentLogger.info('Topic列表加载成功', { count: topics.value.length })
    } else {
      throw new Error(response.data.message || '获取Topic失败')
    }
  } catch (error) {
    componentLogger.error('加载Topic列表失败', error)
    ElMessage.error('加载Topic列表失败')
  } finally {
    topicsLoading.value = false
  }
}

// Topic搜索处理
const handleTopicSearch = () => {
  if (!topicSearchKeyword.value.trim()) {
    // 如果搜索关键词为空，显示所有Topic
    filteredTopics.value = [...topics.value]
  } else {
    // 按关键词过滤Topic
    const keyword = topicSearchKeyword.value.toLowerCase()
    filteredTopics.value = topics.value.filter(topic => 
      topic.name.toLowerCase().includes(keyword)
    )
  }
}

// 高亮搜索关键词
const highlightSearchKeyword = (text) => {
  if (!topicSearchKeyword.value.trim()) return text
  
  const keyword = topicSearchKeyword.value.trim()
  const regex = new RegExp(`(${keyword})`, 'gi')
  return text.replace(regex, '<mark style="background-color: #fff3cd; padding: 0 2px;">$1</mark>')
}

// Topic自动完成搜索
const queryTopicSuggestions = (queryString, callback) => {
  // 如果没有加载Topic列表，先加载
  if (topics.value.length === 0) {
    loadTopics().then(() => {
      performTopicSearch(queryString, callback)
    })
  } else {
    performTopicSearch(queryString, callback)
  }
}

// 执行Topic搜索
const performTopicSearch = (queryString, callback) => {
  if (!queryString || queryString.trim() === '') {
    // 如果没有输入，显示前10个Topic作为提示
    const suggestions = topics.value.slice(0, 10).map(topic => ({
      value: topic.name
    }))
    callback(suggestions)
    return
  }
  
  // 模糊搜索匹配
  const keyword = queryString.toLowerCase()
  const filteredTopics = topics.value.filter(topic => 
    topic.name.toLowerCase().includes(keyword)
  ).map(topic => ({
    value: topic.name
  }))
  
  // 最多显示20个建议
  callback(filteredTopics.slice(0, 20))
}

// 高亮Topic名称中的匹配部分
const highlightTopicName = (topicName, queryString) => {
  if (!queryString || queryString.trim() === '') return topicName
  
  const keyword = queryString.trim()
  const regex = new RegExp(`(${keyword})`, 'gi')
  return topicName.replace(regex, '<mark style="background-color: #e6f7ff; color: #1890ff; padding: 0 2px; border-radius: 2px;">$1</mark>')
}

// 处理Topic选择
const handleTopicSelect = (item) => {
  config.topic = item.value
  componentLogger.info('通过自动完成输入或选择topic', { topic: item.value })
}

// 加载最新消息
const loadMessages = async () => {
  if (!monitoring.value) return
  
  try {
    messagesLoading.value = true
    const response = await api.get('/kafka-listener/messages')
    const newMessages = response.data.data.messages || []
    
    // 为新消息添加展开状态，默认折叠
    const messagesWithExpandState = newMessages.map(message => ({
      ...message,
      expanded: false // 默认折叠
    }))
    
    messages.value = messagesWithExpandState
    
    // 自动滚动到底部
    if (displayConfig.auto_scroll) {
      nextTick(() => {
        if (messageContainer.value) {
          messageContainer.value.scrollTop = messageContainer.value.scrollHeight
        }
      })
    }
  } catch (error) {
    componentLogger.error('加载消息失败', error)
  } finally {
    messagesLoading.value = false
  }
}

// 清空消息
const clearMessages = async () => {
  try {
    await api.post('/kafka-listener/messages/clear')
    messages.value = []
    ElMessage.success('消息列表已清空')
  } catch (error) {
    ElMessage.error('清空消息失败: ' + (error.response?.data?.message || error.message))
    componentLogger.error('清空消息失败', error)
  }
}

// 开始消息轮询
const startMessagePolling = () => {
  if (messageCheckTimer.value) {
    clearInterval(messageCheckTimer.value)
  }
  
  // 立即加载一次
  loadMessages()
  
  // 每2秒轮询一次消息
  messageCheckTimer.value = setInterval(() => {
    loadMessages()
  }, 2000)
}

// 停止消息轮询
const stopMessagePolling = () => {
  if (messageCheckTimer.value) {
    clearInterval(messageCheckTimer.value)
    messageCheckTimer.value = null
  }
}

// 导出数据
// 导出防抖标志
let isExporting = false

const exportData = () => {
  // 防止重复导出
  if (isExporting) {
    componentLogger.warn('导出操作正在进行中，请稍候')
    return
  }
  
  if (messages.value.length === 0) {
    ElMessage.warning('没有数据可导出')
    return
  }
  
  try {
    isExporting = true
    
    const dataStr = JSON.stringify(messages.value, null, 2)
    const blob = new Blob([dataStr], { type: 'application/json' })
    const url = URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = `kafka-messages-${new Date().toISOString().slice(0, 19).replace(/:/g, '-')}.json`
    
    // 使用更安全的方式触发下载
    link.style.display = 'none'
    document.body.appendChild(link)
    link.click()
    
    // 延迟清理，确保下载已开始
    setTimeout(() => {
      document.body.removeChild(link)
      URL.revokeObjectURL(url)
      isExporting = false
    }, 100)
    
    ElMessage.success(`成功导出 ${messages.value.length} 条消息`)
    componentLogger.info('数据导出成功', { count: messages.value.length })
  } catch (error) {
    isExporting = false
    componentLogger.error('导出数据失败', error)
    ElMessage.error('导出数据失败')
  }
}

// 将Python字典格式的字符串转换为标准JSON字符串
const pythonToJson = (str) => {
  return str
    .replace(/'/g, '"')          // 单引号 -> 双引号
    .replace(/False/g, 'false')  // Python False -> JSON false
    .replace(/True/g, 'true')    // Python True -> JSON true
    .replace(/None/g, 'null')    // Python None -> JSON null
}

// 尝试解析字符串为JSON对象（支持Python字典格式）
const tryParseJson = (str) => {
  try {
    // 先尝试标准JSON解析
    return JSON.parse(str)
  } catch {
    // 失败后尝试Python字典格式
    try {
      return JSON.parse(pythonToJson(str))
    } catch {
      return null
    }
  }
}

// 格式化消息显示
const formatMessage = (message) => {
  try {
    let data = message.data
    
    // 处理字符串类型的数据
    if (typeof data === 'string') {
      const parsed = tryParseJson(data)
      if (parsed !== null) {
        return JSON.stringify(parsed, null, 2)
      }
      // 解析失败，返回原始字符串
      return data
    } else if (data && typeof data === 'object') {
      // 处理raw_message字段（可能包含Python字典格式的字符串）
      if (data.raw_message && typeof data.raw_message === 'string') {
        const parsed = tryParseJson(data.raw_message)
        if (parsed !== null) {
          // 将解析后的数据替换raw_message，这样显示更友好
          return JSON.stringify(parsed, null, 2)
        }
      }
      // 如果已经是对象，直接格式化
      return JSON.stringify(data, null, 2)
    }
    
    return String(data)
  } catch (error) {
    componentLogger.error('格式化消息失败', error)
    return String(message.data)
  }
}

// 获取消息预览
const getMessagePreview = (message) => {
  try {
    let data = message.data
    
    // 处理字符串类型
    if (typeof data === 'string') {
      const parsed = tryParseJson(data)
      if (parsed !== null) {
        data = parsed
      } else {
        // 解析失败，截取前100个字符
        return data.length > 100 ? data.substring(0, 100) + '...' : data
      }
    }
    
    // 如果data是对象且包含raw_message，尝试解析它
    if (data && typeof data === 'object' && data.raw_message && typeof data.raw_message === 'string') {
      const parsed = tryParseJson(data.raw_message)
      if (parsed !== null) {
        data = parsed
      }
    }
    
    // 提取关键字段作为预览
    const keys = Object.keys(data)
    const preview = keys.slice(0, 3).map(key => {
      let value = data[key]
      if (typeof value === 'string' && value.length > 20) {
        value = value.substring(0, 20) + '...'
      } else if (typeof value === 'object') {
        value = '[Object]'
      }
      return `${key}: ${value}`
    }).join(', ')
    
    return `{ ${preview}${keys.length > 3 ? `, +${keys.length - 3} more` : ''} }`
  } catch {
    const str = String(message.data)
    return str.length > 100 ? str.substring(0, 100) + '...' : str
  }
}

// 切换消息展开/折叠
const toggleMessageExpand = (index) => {
  if (!messages.value[index]) return
  
  // 为消息对象添加expanded属性
  if (!messages.value[index].hasOwnProperty('expanded')) {
    messages.value[index].expanded = false
  }
  
  messages.value[index].expanded = !messages.value[index].expanded
}

// 复制消息JSON - 使用统一工具
const copyMessage = async (message) => {
  try {
    const jsonText = formatMessage(message)
    await copyText(jsonText, 'JSON')
  } catch (error) {
    componentLogger.error('复制消息失败', error)
  }
}

// 获取策略标签类型
const getStrategyTagType = (strategy) => {
  const types = {
    'latest': 'success',
    'earliest': 'warning', 
    'timestamp': 'info'
  }
  return types[strategy] || 'info'
}

// 获取策略文本
const getStrategyText = (strategy) => {
  const texts = {
    'latest': '最新',
    'earliest': '最早',
    'timestamp': '时间戳'
  }
  return texts[strategy] || strategy
}

// 打开Topic选择器
const openTopicSelector = () => {
  // 重置搜索状态
  topicSearchKeyword.value = ''
  filteredTopics.value = [...topics.value]
  showTopicSelector.value = true
}

const selectTopic = (topicRow) => {
  config.topic = topicRow.name
  showTopicSelector.value = false
  ElMessage.success(`已输入或选择topic: ${topicRow.name}`)
}

// 时间戳选择器相关方法
const initTimestampDialog = () => {
  const now = new Date()
  tempDate.value = now.toISOString().split('T')[0]
  tempTime.value = now.toTimeString().split(' ')[0]
}

const getTimestampPreview = () => {
  if (!tempDate.value || !tempTime.value) return 0
  const dateTime = new Date(`${tempDate.value}T${tempTime.value}`)
  return dateTime.getTime()
}

const confirmTimestamp = () => {
  if (!tempDate.value || !tempTime.value) {
    ElMessage.warning('请选择日期和时间')
    return
  }
  
  const timestamp = getTimestampPreview()
  const dateTimeStr = `${tempDate.value} ${tempTime.value}`
  
  config.start_time = timestamp
  timestampDisplay.value = `${dateTimeStr}`
  
  showTimestampDialog.value = false
  ElMessage.success('时间戳设置成功')
}

const openTimestampDialog = () => {
  if (!config.start_time) {
    initTimestampDialog()
  } else {
    const date = new Date(config.start_time)
    tempDate.value = date.toISOString().split('T')[0]
    tempTime.value = date.toTimeString().split(' ')[0]
  }
  showTimestampDialog.value = true
}

// 快捷时间选择
const setQuickTime = (type) => {
  const now = new Date()
  let targetTime
  
  switch (type) {
    case '1h':
      targetTime = new Date(now.getTime() - 1 * 60 * 60 * 1000)
      break
    case '6h':
      targetTime = new Date(now.getTime() - 6 * 60 * 60 * 1000)
      break
    case '12h':
      targetTime = new Date(now.getTime() - 12 * 60 * 60 * 1000)
      break
    case 'today':
      targetTime = new Date(now)
      targetTime.setHours(0, 0, 0, 0)
      break
    case 'yesterday':
      targetTime = new Date(now)
      targetTime.setDate(now.getDate() - 1)
      targetTime.setHours(0, 0, 0, 0)
      break
    default:
      targetTime = now
  }
  
  // 设置临时日期和时间
  tempDate.value = targetTime.toISOString().split('T')[0]
  tempTime.value = targetTime.toTimeString().split(' ')[0]
  
  ElMessage.success(`已设置为${getQuickTimeLabel(type)}`)
}

// 获取快捷时间标签
const getQuickTimeLabel = (type) => {
  const labelMap = {
    '1h': '1小时前',
    '6h': '6小时前',
    '12h': '12小时前',
    'today': '今天开始',
    'yesterday': '昨天开始'
  }
  return labelMap[type] || '未知'
}

const addCondition = () => {
  config.matchConditions.push({
    type: 'key_value',
    key: '',
    value: ''
  })
}

const removeCondition = (index) => {
  if (config.matchConditions.length > 1) {
    config.matchConditions.splice(index, 1)
  }
}

const startMonitoring = async () => {
  if (!canStart.value) {
    ElMessage.warning('请选择Kafka环境和Topic')
    return
  }

  try {
    const requestData = {
      kafka_config_id: config.kafka_config_id,
      topic: config.topic,
      consume_strategy: config.consume_strategy,
      start_timestamp: config.start_time,
      enable_matching: config.enableMatching,
      logic_operator: config.logicOperator,
      match_conditions: config.enableMatching ? config.matchConditions.filter(condition => 
        condition.type === 'key_value' ? (condition.key && condition.value) : condition.value
      ) : []
    }
    
    const response = await api.post('/kafka-listener/start-listen', requestData)
    if (response.data.success) {
      currentTaskId.value = response.data.data.task_id
      monitoring.value = true
      // 保存Kafka配置信息
      kafkaConfig.value = response.data.data.kafka_config || {}
      // 重置消息统计
      messageStats.value = {
        total_consumed: 0,
        total_matched: 0
      }
    } else {
      throw new Error(response.data.message || '启动监听失败')
    }
    monitoringStartTime.value = Date.now()
    
    // 启动定时器更新监听时长
    durationTimer.value = setInterval(() => {
      if (monitoringStartTime.value) {
        monitoringDuration.value = Math.floor((Date.now() - monitoringStartTime.value) / 1000)
      }
    }, 1000)
    
    // 启动状态轮询
    startStatusPolling()
    
    // 启动消息轮询
    startMessagePolling()
    
    componentLogger.info('开始监听Kafka数据', { 
      task_id: currentTaskId.value,
      topic: config.topic
    })
    ElMessage.success('开始监听Kafka数据')
  } catch (error) {
    componentLogger.error('启动监听失败', error)
    ElMessage.error('启动监听失败')
  }
}

// 启动状态轮询
const startStatusPolling = () => {
  if (statusCheckTimer.value) {
    clearInterval(statusCheckTimer.value)
  }
  
  // 每2秒检查一次状态
  statusCheckTimer.value = setInterval(async () => {
    try {
      const response = await api.get('/kafka-listener/status')
      if (response.data.success) {
        const status = response.data.data
        
        // 添加调试日志
        componentLogger.info('状态轮询结果', { 
          backend_status: status.status, 
          backend_task_id: status.task_id, 
          frontend_monitoring: monitoring.value,
          frontend_task_id: currentTaskId.value
        })
        
        // 更新消息统计
        if (status.stats) {
          messageStats.value = status.stats
        }
        
        if (status.status === 'running') {
          // 任务正在运行，检查任务ID是否发生变化
          if (currentTaskId.value && status.task_id !== currentTaskId.value) {
            componentLogger.warn('检测到任务ID变化', {
              old_task_id: currentTaskId.value,
              new_task_id: status.task_id
            })
            
            // 方案：同步到新任务，让用户可以停止它，而不是直接重置状态
            componentLogger.info('同步到新任务状态，保持监听状态可操作')
            ElMessage.warning({
              message: '检测到新的监听任务正在运行，已同步状态',
              duration: 3000
            })
            
            // 更新到新任务ID，保持monitoring状态为true
            currentTaskId.value = status.task_id
            monitoringStartTime.value = Date.now() - (status.duration_seconds * 1000)
            
            // 更新Kafka配置信息
            if (status.kafka_config) {
              kafkaConfig.value = status.kafka_config
              // 同步配置到表单
              if (status.kafka_config.config_id) {
                config.kafka_config_id = status.kafka_config.config_id
              }
              if (status.topic) {
                config.topic = status.topic
              }
            }
            
            // 清空旧消息，准备接收新任务的消息
            messages.value = []
            
            // 确保monitoring状态为true，这样停止按钮才可用
            if (!monitoring.value) {
              monitoring.value = true
            }
            
            // 不需要return，继续正常处理
          }
          
          // 更新任务ID（首次启动或正常更新）
          if (!currentTaskId.value) {
            currentTaskId.value = status.task_id
          }
          
          // 确保前端状态与后端一致
          if (!monitoring.value) {
            monitoring.value = true
            monitoringStartTime.value = Date.now() - (status.duration_seconds * 1000)
          }
          // 更新Kafka配置信息
          if (status.kafka_config) {
            kafkaConfig.value = status.kafka_config
          }
        } else if (status.status === 'idle') {
          // 任务已停止
          if (monitoring.value) {
            componentLogger.info('检测到任务已停止')
            ElMessage.warning('监听任务已停止')
            monitoring.value = false
            currentTaskId.value = null
            monitoringStartTime.value = null
            kafkaConfig.value = {}
            stopStatusPolling()
            stopMessagePolling()
          }
        }
      }
    } catch (error) {
      componentLogger.error('检查状态失败', error)
      // 如果状态检查失败多次，可能任务已经停止
      if (monitoring.value) {
        componentLogger.warn('状态检查失败，可能任务已停止')
      }
    }
  }, 2000)
}

// 停止状态轮询
const stopStatusPolling = () => {
  if (statusCheckTimer.value) {
    clearInterval(statusCheckTimer.value)
    statusCheckTimer.value = null
  }
}

const stopMonitoring = async () => {
  // 停止状态轮询
  stopStatusPolling()
  
  // 停止消息轮询
  stopMessagePolling()
  
  // 如果有正在运行的任务，调用停止接口
  if (monitoring.value && currentTaskId.value) {
    try {
      await api.post('/kafka-listener/stop-listen')
      componentLogger.info('停止监听任务', { task_id: currentTaskId.value })
      ElMessage.success('已停止监听任务，消息数据已保留供查看')
    } catch (error) {
      componentLogger.error('停止监听任务失败', error)
      ElMessage.error('停止监听任务失败')
    }
  }
  
  // 重置监听状态，但保留消息数据
  monitoring.value = false
  
  // 重置消息统计
  messageStats.value = {
    total_consumed: 0,
    total_matched: 0
  }
  currentTaskId.value = null
  monitoringStartTime.value = null
  // 注意：不再清空 messages.value，保留消息供用户查看
  
  // 清理定时器
  if (durationTimer.value) {
    clearInterval(durationTimer.value)
    durationTimer.value = null
  }
}



// 辅助函数保留以备将来扩展
const formatTime = (timestamp) => {
  return new Date(timestamp).toLocaleString()
}

// 生命周期
onMounted(() => {
  // 不自动加载环境列表，等待用户手动选择
  componentLogger.info('Kafka监听页面加载完成')
})

onUnmounted(() => {
  stopMonitoring()
  stopStatusPolling()
  if (durationTimer.value) {
    clearInterval(durationTimer.value)
  }
})
</script>

<style scoped>
.page-container {
  padding: 0;
  min-height: calc(100vh - 60px);
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 30px;
  padding-bottom: 20px;
  border-bottom: 1px solid #e4e7ed;
}

.title-with-back {
  display: flex;
  align-items: flex-start;
  gap: 15px;
}

.blue-return-button {
  background: linear-gradient(135deg, #409eff 0%, #66b3ff 100%);
  border: none;
  border-radius: 8px;
  padding: 8px 16px;
  font-weight: 500;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
  transition: all 0.3s ease;
  flex-shrink: 0;
  margin-top: 2px;
}

.blue-return-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(64, 158, 255, 0.4);
  background: linear-gradient(135deg, #66b3ff 0%, #409eff 100%);
}

.title-content {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.title-main {
  display: flex;
  align-items: center;
  gap: 12px;
}

.title-icon {
  font-size: 28px;
  color: #67C23A;
  background: linear-gradient(135deg, #67C23A 0%, #85CE61 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.page-title h2 {
  margin: 0;
  color: #303133;
  font-size: 24px;
  font-weight: 600;
}

.page-description {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 10px 16px;
  background: linear-gradient(135deg, #f5f7fa 0%, #ecf3fc 100%);
  border-left: 3px solid #67C23A;
  border-radius: 6px;
  color: #606266;
  font-size: 14px;
  line-height: 1.6;
}

.page-description .el-icon {
  font-size: 16px;
  color: #67C23A;
  flex-shrink: 0;
}

.page-description span {
  flex: 1;
}

.config-panel {
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.card-header-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.card-icon {
  font-size: 20px;
  color: #67C23A;
  background: linear-gradient(135deg, #67C23A 0%, #85CE61 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.filter-rules {
  margin-top: 16px;
}

.rule-item {
  margin-bottom: 10px;
}

.data-panel {
  flex: 1;
  min-height: 600px;
}

.data-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}

.data-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.data-stats {
  display: flex;
  gap: 40px;
  margin-bottom: 20px;
  padding: 15px;
  background: #f8f9fa;
  border-radius: 6px;
}

.message-list {
  height: 500px;
  overflow-y: auto;
  border: 1px solid #EBEEF5;
  border-radius: 4px;
  padding: 10px;
}

.message-item {
  margin-bottom: 15px;
  padding: 15px;
  border: 1px solid #E4E7ED;
  border-radius: 6px;
  background: #FAFAFA;
  border-left: 4px solid #67C23A;
}

.message-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.message-meta {
  display: flex;
  align-items: center;
  gap: 10px;
}

.message-sequence {
  font-weight: 600;
  color: #409EFF;
}

.message-time {
  font-size: 12px;
  color: #909399;
}

.matched-rules {
  display: flex;
  gap: 5px;
  flex-wrap: wrap;
}

.message-content {
  margin-top: 10px;
}

.monitoring-waiting {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 40px;
  color: #909399;
  font-size: 16px;
}

/* 匹配配置样式 */
.match-config-container {
  margin-top: 16px;
}

.match-global-control {
  margin-bottom: 20px;
}

.match-enable-selector {
  padding: 12px 0;
}

.match-conditions {
  margin-top: 16px;
}

.logic-selector {
  margin-bottom: 20px;
  padding: 16px;
  background: #f8f9fa;
  border-radius: 8px;
  border: 1px solid #e4e7ed;
}

.control-label {
  font-size: 14px;
  font-weight: 600;
  color: #303133;
  margin-right: 12px;
}

.logic-operator {
  margin-top: 12px;
}

.logic-operator .el-radio {
  margin-right: 24px;
  margin-bottom: 8px;
}

.conditions-list {
  margin-top: 16px;
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: flex-start;
}

.condition-item {
  flex: 0 1 calc(50% - 8px); /* 默认每行显示2个 */
  min-width: 380px; /* 最小宽度，确保内容不会挤压 */
  max-width: calc(50% - 8px); /* 最大宽度限制 */
  box-sizing: border-box;
}

/* 大屏幕可以显示3个 */
@media (min-width: 1600px) {
  .condition-item {
    flex: 0 1 calc(33.333% - 11px); /* 每行显示3个 */
    max-width: calc(33.333% - 11px);
  }
}

/* 中等屏幕显示2个 */
@media (max-width: 1400px) and (min-width: 900px) {
  .condition-item {
    flex: 0 1 calc(50% - 8px);
    max-width: calc(50% - 8px);
  }
}

/* 小屏幕自动变为单列 */
@media (max-width: 900px) {
  .condition-item {
    flex: 0 1 100%;
    max-width: 100%;
  }
}

.condition-card {
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  height: 100%; /* 确保同行卡片高度一致 */
  display: flex;
  flex-direction: column;
}

.condition-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.condition-number {
  font-size: 14px;
  font-weight: 600;
  color: #409eff;
}

.condition-content {
  display: flex;
  flex-direction: column;
  gap: 12px; /* 减小间距 */
  flex: 1; /* 占据剩余空间 */
}

.condition-row {
  display: flex;
  align-items: flex-start;
  gap: 12px; /* 减小间距 */
  flex-wrap: wrap;
}

.condition-label {
  font-size: 14px;
  font-weight: 500;
  color: #606266;
  min-width: 80px;
}

.condition-type {
  flex: 1;
}

.input-group {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  min-width: 180px; /* 确保输入框有最小宽度 */
}

.input-label {
  font-size: 12px;
  color: #909399;
  font-weight: 500;
}

.add-condition {
  flex: 0 1 100%; /* 占满整行 */
  text-align: center;
  padding: 16px;
  border: 2px dashed #d9d9d9;
  border-radius: 8px;
  background: #fafafa;
  margin-top: 0;
}

/* JSON Viewer 样式优化 */
:deep(.jv-container) {
  background: white;
  border: 1px solid #DCDFE6;
  border-radius: 4px;
}

:deep(.jv-code) {
  padding: 15px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .page-header {
    flex-direction: column;
    gap: 10px;
  }
  
  .data-header {
    flex-direction: column;
    gap: 10px;
    align-items: flex-start;
  }
  
  .data-stats {
    flex-direction: column;
    gap: 20px;
  }
}

/* Topic自动完成样式 */
.autocomplete-item {
  padding: 4px 8px;
  line-height: 1.5;
}

.autocomplete-item:hover {
  background-color: #f5f7fa;
}

/* Topic选择器样式 */
.topic-suggestion-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
}

.topic-suggestion-item .el-icon {
  color: #67c23a;
  font-size: 14px;
}

.topic-suggestion-item span {
  font-size: 14px;
  color: #303133;
}

/* 优化自动完成下拉框的样式 */
:deep(.el-autocomplete-suggestion) {
  max-height: 300px;
  overflow-y: auto;
}

:deep(.el-autocomplete-suggestion__wrap) {
  max-height: 300px;
}

:deep(.el-autocomplete-suggestion li) {
  padding: 8px 12px;
  border-bottom: 1px solid #f0f0f0;
}

:deep(.el-autocomplete-suggestion li:last-child) {
  border-bottom: none;
}

:deep(.el-autocomplete-suggestion li.highlighted) {
  background-color: #e6f7ff;
}

/* 时间戳选择器样式 */
.timestamp-dialog {
  padding: 20px 0;
}

.timestamp-info {
  margin-bottom: 24px;
}

.timestamp-selector {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.datetime-inputs {
  display: flex;
  gap: 24px;
  align-items: center;
}

.input-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.input-group label {
  font-size: 14px;
  font-weight: 500;
  color: #606266;
}

.timestamp-preview {
  background: #f8f9fa;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  padding: 16px;
}

.preview-info label {
  font-size: 14px;
  font-weight: 500;
  color: #303133;
  margin-bottom: 12px;
  display: block;
}

.preview-values {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.preview-item {
  display: flex;
  align-items: center;
  gap: 12px;
}

.preview-item .label {
  font-size: 13px;
  color: #909399;
  min-width: 80px;
}

.preview-item code {
  background: #f0f0f0;
  padding: 4px 8px;
  border-radius: 4px;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 13px;
  color: #e6a23c;
}

/* 快捷选择区域样式 */
.quick-select-section {
  margin-top: 24px;
  padding: 16px;
  background: #f8f9fa;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
}

.quick-select-info {
  margin-bottom: 12px;
}

.quick-select-info label {
  font-size: 14px;
  font-weight: 500;
  color: #303133;
  display: block;
  margin-bottom: 4px;
}

.usage-tip {
  font-size: 12px;
  color: #909399;
  margin: 0;
  line-height: 1.4;
}

.quick-select-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.quick-select-buttons .el-button {
  margin: 0;
  border-radius: 16px;
  padding: 6px 12px;
  font-size: 12px;
  transition: all 0.2s ease;
}

.quick-select-buttons .el-button:hover {
  background-color: #409eff;
  border-color: #409eff;
  color: white;
  transform: translateY(-1px);
}

/* 新增的消息展示样式 */
.header-left {
  display: flex;
  align-items: center;
  gap: 10px;
}

.header-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.message-index {
  font-weight: 600;
  color: #409EFF;
  font-size: 14px;
}

.json-viewer {
  background: #f8f9fa;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  overflow: hidden;
}

.json-content {
  margin: 0;
  padding: 16px;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
  font-size: 13px;
  line-height: 1.6;
  color: #2c3e50;
  background: #f8f9fa;
  overflow-x: auto;
  white-space: pre;
  border: none;
  max-height: 400px;
  overflow-y: auto;
}

.message-preview {
  background: #f0f2f5;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  padding: 10px 12px;
  margin-top: 8px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.message-preview:hover {
  background: #e6f7ff;
  border-color: #91d5ff;
}

.preview-text {
  color: #666;
  font-size: 13px;
  line-height: 1.4;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
}

/* 匹配的消息特殊样式 */
.message-item.matched .message-preview {
  background: #f6ffed;
  border-color: #b7eb8f;
}

.message-item.matched .json-viewer {
  background: #f6ffed;
  border-color: #b7eb8f;
}

.message-item.matched .json-content {
  background: #f6ffed;
}

/* 后台任务信息样式 */
.backend-task-info {
  margin-bottom: 20px;
}

.backend-task-info .el-alert {
  margin-bottom: 0;
}

.backend-task-info p {
  margin: 6px 0;
  line-height: 1.5;
}

.backend-task-info strong {
  color: #303133;
}

/* 消息列表样式 */
.messages-container {
  max-height: 600px;
  overflow-y: auto;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  background: #fff;
}

.message-item {
  border-bottom: 1px solid #f0f0f0;
  padding: 12px 16px;
  transition: background-color 0.2s;
}

.message-item:hover {
  background-color: #f8f9fa;
}

.message-item:last-child {
  border-bottom: none;
}

.message-item.matched {
  border-left: 4px solid #67C23A;
  background-color: #f0f9ff;
}

.message-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
  font-size: 12px;
  color: #909399;
}

.message-index {
  font-weight: 600;
  color: #606266;
}

.message-time {
  font-family: 'Monaco', 'Consolas', monospace;
}

.message-content {
  background: #f8f9fa;
  border-radius: 4px;
  padding: 8px 12px;
  border: 1px solid #e4e7ed;
}

.message-content pre {
  margin: 0;
  font-family: 'Monaco', 'Consolas', monospace;
  font-size: 12px;
  line-height: 1.4;
  white-space: pre-wrap;
  word-break: break-all;
  color: #2c3e50;
}

.no-messages {
  padding: 40px 20px;
  text-align: center;
}

.listening-status {
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.8; }
}

/* Kafka配置面板样式 */
.kafka-config-panel .el-card {
  border: 1px solid #e4e7ed;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.config-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 12px 24px;
}

.config-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 0;
  border-bottom: 1px solid #f0f0f0;
}

.config-item:last-child {
  border-bottom: none;
}

.config-item label {
  font-weight: 600;
  color: #606266;
  min-width: 120px;
  font-size: 13px;
}

.config-item span {
  color: #303133;
  font-size: 13px;
  flex: 1;
  word-break: break-all;
  overflow-wrap: break-word;
  max-width: 100%;
}

.config-item code {
  background: #f5f7fa;
  padding: 2px 6px;
  border-radius: 3px;
  font-family: 'Monaco', 'Consolas', monospace;
  font-size: 12px;
  color: #e6a23c;
  border: 1px solid #ebeef5;
}

.topic-text {
  display: inline-block;
  font-family: 'Monaco', 'Consolas', monospace;
  font-size: 12px;
  padding: 4px 8px;
  background: #f0f9ff;
  border: 1px solid #91d5ff;
  border-radius: 4px;
  color: #1890ff;
  font-weight: 500;
  max-width: 100%;
  word-break: break-all;
  overflow-wrap: break-word;
  line-height: 1.5;
}
</style>

